<?php

namespace app\common;

use think\Exception;

/**
 * 苹果支付模型
 */
class ApplePay
{
    protected static $appleCode = [
        21000 => 'App Store无法读取你提供的JSON数据',
        21002 => '收据数据不符合格式',
        21003 => '收据无法被验证',
        21004 => '你提供的共享密钥和账户的共享密钥不一致',
        21005 => '收据服务器当前不可用',
        21006 => '收据是有效的，但订阅服务已经过期。当收到这个信息时，解码后的收据信息也包含在返回内容中',
        21007 => '收据信息是测试用（sandbox），但却被发送到产品环境中验证',
        21008 => '收据信息是产品环境中使用，但却被发送到测试环境中验证'
    ];

    protected static $official_url = 'https://buy.itunes.apple.com/verifyReceipt';//苹果支付正式环境
    protected static $sandbox_url = 'https://sandbox.itunes.apple.com/verifyReceipt';//苹果支付沙箱环境
    protected static $password = '';//共享秘钥
    protected static $bundle_id = 'com.lm.weigangwan';//包名

    /**
     * 苹果充值验证支付票据完成订单接口
     * @param $receipt 苹果支付票据信息
     * @return mixed
     * @throws Exception
     */
    public static function verifyReceipt($receipt)
    {
//        $json_item = json_encode(['receipt-data' => $receipt, 'password' => self::$password], 256);
        $json_item = json_encode(['receipt-data' => $receipt], 256);

        //模拟post提交,将前端获取到的凭证,去和苹果换取详细的支付信息
        $result = self::httpPostJson($json_item, self::$official_url);

        if ($result['status'] == '21007') {//沙箱环境
//            throw new Exception('请使用正式环境发起支付');
            //验证失败,返回app错误状态
            $result = self::httpPostJson($json_item, self::$sandbox_url);
        }
        //如果检测到等于0就是支付成功,其他的错误码去获取对应错误信息
        if ($result['status'] !== 0) {
            //验证失败 返回app错误状态
            throw new Exception(self::$appleCode[$result['status']]);
        }
        $receipt = $result['receipt'];
        //判断包名bundle_id
        $package_name = $receipt['bundle_id'] ?? '';
        if (!$package_name) {
            throw new Exception('bundle_id缺失');
        }
        if ($package_name != self::$bundle_id) {
            throw new Exception('非法请求,包名有误');
        }

        return $result;
    }

    /**
     * 发送post请求
     * @param $json
     * @param $url
     * @return mixed
     */
    private static function httpPostJson($json, $url)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);  //这两行一定要加，不加会报SSL 错误
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $errmsg = curl_error($ch);
        curl_close($ch);

        $data = json_decode($response, true);

        return $data;
    }
}